#include "stdafx.h"
#include "gp.h"
#include "gp_XY.h"
#include "gp_Mat2d.h"

 gp_XY::gp_XY () : x(0.), y(0.) { } 

 gp_XY::gp_XY (const double X,
		     const double Y) :  x (X),  y (Y) { }

 void gp_XY::SetCoord (const int i,
			     const double X)
{
	Standard_OutOfRange_Raise_if(i < 1 || i > 2, NULL);
  (&x)[i-1] = X;
}

 void gp_XY::SetCoord (const double X,
			     const double Y)
{ x = X;  y = Y; }

 void gp_XY::SetX (const double X)
{ x = X; }

 void gp_XY::SetY (const double Y)
{ y = Y; }

 double gp_XY::Coord (const int i) const
{
	Standard_OutOfRange_Raise_if(i < 1 || i > 2, NULL);
  return (&x)[i-1];
}

 void gp_XY::Coord (double& X,
			  double& Y) const
{ X = x;  Y = y; }

 double gp_XY::X () const
{ return x; }

 double gp_XY::Y () const
{ return y; }

 double gp_XY::Modulus () const
{ 
  return sqrt (x * x + y * y);
}

 double gp_XY::SquareModulus () const
{
  return x * x + y * y;
}

 void gp_XY::Add (const gp_XY& Other) {
  x += Other.x;
  y += Other.y;
}

 gp_XY gp_XY::Added (const gp_XY& Other) const {
  return gp_XY(x + Other.X(),y + Other.Y());
}

 double gp_XY::Crossed (const gp_XY& Right) const {
  return x * Right.y - y * Right.x;
}

 double gp_XY::CrossMagnitude (const gp_XY& Right) const
{
  double val = x * Right.y - y * Right.x;
  if (val < 0) val = - val;
  return val;
}

 double gp_XY::CrossSquareMagnitude (const gp_XY& Right) const {
  double Zresult =  x * Right.y - y * Right.x;
  return Zresult * Zresult;
}

 void gp_XY::Divide (const double Scalar)
{
  x /= Scalar;
  y /= Scalar;
}

 gp_XY gp_XY::Divided (const double Scalar) const {
  return gp_XY(x / Scalar,y / Scalar);
}

 double gp_XY::Dot (const gp_XY& Other) const
{
  return x * Other.x + y * Other.y;
}

 void gp_XY::Multiply (const double Scalar)
{
  x *= Scalar;
  y *= Scalar;
}

 void gp_XY::Multiply (const gp_XY& Other)
{
  x *= Other.x;
  y *= Other.y;
}

 void gp_XY::Multiply (const gp_Mat2d& Matrix)
{
  double Xresult = Matrix.matrix[0][0] * x + Matrix.matrix[0][1] * y;
  y                     = Matrix.matrix[1][0] * x + Matrix.matrix[1][1] * y;
  x                     = Xresult;
}

 gp_XY gp_XY::Multiplied (const double Scalar) const {
  return gp_XY(x * Scalar,y * Scalar);
}

 gp_XY gp_XY::Multiplied (const gp_XY& Other) const {
  return(gp_XY(x * Other.X(),y * Other.Y()));
}

 gp_XY gp_XY::Multiplied (const gp_Mat2d& Matrix) const
{
  return gp_XY (Matrix.matrix[0][0] * x + Matrix.matrix[0][1] * y,
		Matrix.matrix[1][0] * x + Matrix.matrix[1][1] * y);
}

 void gp_XY::Normalize ()
{
  double D = Modulus();
  Standard_ConstructionError_Raise_if(D <= gp::Resolution(), "");
  x = x / D;   y = y / D;
}

 gp_XY gp_XY::Normalized () const
{
  double D = Modulus();
  Standard_ConstructionError_Raise_if(D <= gp::Resolution(), "");
  return gp_XY (x / D, y / D);
}

 void gp_XY::Reverse ()
{  x = - x;    y = - y;  }

 gp_XY gp_XY::Reversed () const
{
  gp_XY Coord2D = *this;
  Coord2D.Reverse();
  return Coord2D;
}

 void gp_XY::SetLinearForm (const double L,
				  const gp_XY& Left,
				  const double R,
				  const gp_XY& Right) {
  x = L * Left.x + R * Right.x;
  y = L * Left.y + R * Right.y;
}

 void gp_XY::SetLinearForm (const double L,
				  const gp_XY& Left,
				  const gp_XY& Right) {
  x = L * Left.x + Right.x;
  y = L * Left.y + Right.y;
}

 void gp_XY::SetLinearForm (const gp_XY& Left,
				  const gp_XY& Right) {
  x = Left.x + Right.x;
  y = Left.y + Right.y;
}

 void gp_XY::SetLinearForm (const double A1,
				  const gp_XY& XY1,
				  const double A2,
				  const gp_XY& XY2,
				  const gp_XY& XY3) {
  x = A1 * XY1.x + A2 * XY2.x + XY3.x;
  y = A1 * XY1.y + A2 * XY2.y + XY3.y;
}

 void gp_XY::Subtract (const gp_XY& Right)
{
  x -= Right.x;
  y -= Right.y;
}

 gp_XY gp_XY::Subtracted (const gp_XY& Right) const
{
  gp_XY Coord2D = *this;
  Coord2D.Subtract(Right);
  return Coord2D;
}

 gp_XY operator* (const gp_Mat2d& Matrix,
			const gp_XY& Coord1) {
  return Coord1.Multiplied(Matrix);
}

 gp_XY operator* (const double Scalar,
			const gp_XY& Coord1) {
  return Coord1.Multiplied(Scalar);
}

 bool gp_XY::IsEqual (const gp_XY& Other,
	 const double Tolerance) const
 {
	 double val;
	 val = x - Other.x;
	 if (val < 0) val = - val;
	 if (val > Tolerance) return false;
	 val = y - Other.y;
	 if (val < 0) val = - val;
	 if (val > Tolerance) return false;
	 return true;
 }

